home *** CD-ROM | disk | FTP | other *** search
/ Chip 2000 October / CHIP Turkiye Ekim 2000.iso / prog / naps / 04 / setup.exe / Gnucleus / Base64.cpp < prev    next >
C/C++ Source or Header  |  2000-07-15  |  5KB  |  206 lines

  1. /********************************************************************************
  2.  
  3.     Gnucleus - A node application for the Gnutella network
  4.     Copyright (C) 2000 John Marshall
  5.  
  6.     This program is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  
  19.     For support, questions, comments, etc...
  20.     E-Mail: 
  21.         swabby@c0re.net
  22.     
  23.     Address:
  24.         21 Cadogan Way
  25.         Nashua, NH, USA 03062
  26.  
  27. ********************************************************************************/
  28.  
  29. //////////////////////////////////////////////////////////////////////
  30. //
  31. //  Base64.cpp: implementation of the CBase64 class.
  32. //  
  33. //    Author: Wes Clyburn (clyburnw@enmu.edu)
  34. //  Modified and adapted by: Nathan Brown (shiften@dittosrush.com)
  35. // 
  36. //  This code was practically stolen from:
  37. //  Dr. Dobb's Journal, September 1995, 
  38. //  "Mime and Internet Mail", by Tim Kientzle
  39.  
  40.  
  41. #include "stdafx.h"
  42. #include "Base64.h"
  43.  
  44. #ifdef _DEBUG
  45. #undef THIS_FILE
  46. static char THIS_FILE[]=__FILE__;
  47. #define new DEBUG_NEW
  48. #endif
  49.  
  50. // Static Member Initializers
  51. //
  52.  
  53. // The 7-bit alphabet used to encode binary information
  54. CString CBase64::m_sBase64Alphabet = 
  55. _T( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" );
  56.  
  57. int CBase64::m_nMask[] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
  58.  
  59. //////////////////////////////////////////////////////////////////////
  60. // Construction/Destruction
  61. //////////////////////////////////////////////////////////////////////
  62.  
  63. CBase64::CBase64()
  64. {
  65.     m_lBitStorage = 0;
  66.     m_nInputSize = 0;
  67.     m_nBitsRemaining = 0;
  68.     m_lBitStorage = 0;
  69.     m_szInput = NULL;
  70.  
  71.  
  72. }
  73.  
  74. CBase64::~CBase64()
  75. {
  76. }
  77.  
  78. CString CBase64::Encode(LPCTSTR szEncoding, int nSize)
  79. {
  80.     CString sOutput = _T( "" );
  81.     int nNumBits = 6;
  82.     UINT nDigit;
  83.     int lp = 0;
  84.  
  85.     ASSERT( szEncoding != NULL );
  86.     if( szEncoding == NULL )
  87.         return sOutput;
  88.     m_szInput = szEncoding;
  89.     m_nInputSize = nSize;
  90.  
  91.     m_nBitsRemaining = 0;
  92.     nDigit = read_bits( nNumBits, &nNumBits, lp );
  93.     while( nNumBits > 0 )
  94.     {
  95.         sOutput += m_sBase64Alphabet[ (int)nDigit ];
  96.         nDigit = read_bits( nNumBits, &nNumBits, lp );
  97.     }
  98. /*
  99.     // Pad with '=' as per RFC 1521
  100.     while( sOutput.GetLength() % 4 != 0 )
  101.     {
  102.         sOutput += '=';
  103.     }
  104. */
  105.     return sOutput;
  106. }
  107.  
  108. // The size of the output buffer must not be less than
  109. // 3/4 the size of the input buffer. For simplicity,
  110. // make them the same size.
  111. int CBase64::Decode(LPCTSTR szDecoding, LPTSTR szOutput)
  112. {
  113.     CString sInput;
  114.     int c, lp =0;
  115.     int nDigit;
  116.     int nDecode[ 256 ];
  117.  
  118.     ASSERT( szDecoding != NULL );
  119.     ASSERT( szOutput != NULL );
  120.     if( szOutput == NULL )
  121.         return 0;
  122.     if( szDecoding == NULL )
  123.         return 0;
  124.     sInput = szDecoding;
  125.     if( sInput.GetLength() == 0 )
  126.         return 0;
  127.  
  128.     m_nBitsRemaining = 0;
  129.  
  130.     // Build Decode Table
  131.     //
  132.     for( int i = 0; i < 256; i++ ) 
  133.         nDecode[i] = -2; // Illegal digit
  134.     for( i=0; i < 64; i++ )
  135.     {
  136.         nDecode[ m_sBase64Alphabet[ i ] ] = i;
  137.         nDecode[ m_sBase64Alphabet[ i ] | 0x80 ] = i; // Ignore 8th bit
  138.         nDecode[ '=' ] = -1; 
  139.         nDecode[ '=' | 0x80 ] = -1; // Ignore MIME padding char
  140.     }
  141.  
  142.     // Clear the output buffer
  143.     memset( szOutput, 0, sInput.GetLength() + 1 );
  144.  
  145.     // Decode the Input
  146.     //
  147.     for( lp = 0, i = 0; lp < sInput.GetLength(); lp++ )
  148.     {
  149.         c = sInput[ lp ];
  150.         nDigit = nDecode[ c & 0x7F ];
  151.         if( nDigit < -1 ) 
  152.         {
  153.             return 0;
  154.         } 
  155.         else if( nDigit >= 0 ) 
  156.             // i (index into output) is incremented by write_bits()
  157.             write_bits( nDigit & 0x3F, 6, szOutput, i );
  158.     }    
  159.     return i;
  160. }
  161.  
  162. UINT CBase64::read_bits(int nNumBits, int * pBitsRead, int& lp)
  163. {
  164.     ULONG lScratch;
  165.     while( ( m_nBitsRemaining < nNumBits ) && 
  166.            ( lp < m_nInputSize ) ) 
  167.     {
  168.         int c = m_szInput[ lp++ ];
  169.         m_lBitStorage <<= 8;
  170.         m_lBitStorage |= (c & 0xff);
  171.         m_nBitsRemaining += 8;
  172.     }
  173.     if( m_nBitsRemaining < nNumBits ) 
  174.     {
  175.         lScratch = m_lBitStorage << ( nNumBits - m_nBitsRemaining );
  176.         *pBitsRead = m_nBitsRemaining;
  177.         m_nBitsRemaining = 0;
  178.     } 
  179.     else 
  180.     {
  181.         lScratch = m_lBitStorage >> ( m_nBitsRemaining - nNumBits );
  182.         *pBitsRead = nNumBits;
  183.         m_nBitsRemaining -= nNumBits;
  184.     }
  185.     return (UINT)lScratch & m_nMask[nNumBits];
  186. }
  187.  
  188.  
  189. void CBase64::write_bits(UINT nBits,
  190.                          int nNumBits,
  191.                          LPTSTR szOutput,
  192.                          int& i)
  193. {
  194.     UINT nScratch;
  195.  
  196.     m_lBitStorage = (m_lBitStorage << nNumBits) | nBits;
  197.     m_nBitsRemaining += nNumBits;
  198.     while( m_nBitsRemaining > 7 ) 
  199.     {
  200.         nScratch = m_lBitStorage >> (m_nBitsRemaining - 8);
  201.         szOutput[ i++ ] = nScratch & 0xFF;
  202.         m_nBitsRemaining -= 8;
  203.     }
  204. }
  205.  
  206.